import { Dimension } from '../../common/dimension';
import { Vector } from '../../common/vector';
import { RendererComponent } from './renderer.component';

export interface IAnimationFrameInfo {
  sourceLocation: Vector;
  sourceDimension: Dimension;
}

export class SpriteAnimationRendererComponent extends RendererComponent {
  #elapsed: number = 0;
  #currentFrameIndex: number = 0;
  #isFirstRunPassed: boolean = false;

  get isComplete(): boolean {
    return this.isInfinite ? false : this.#isFirstRunPassed;
  }

  get currentFrame(): IAnimationFrameInfo {
    return this.frames[this.#currentFrameIndex];
  }

  constructor(
    public sprite: HTMLImageElement,
    public dimension: Dimension,
    public frames: IAnimationFrameInfo[],
    public speed: number,
    public isInfinite: boolean
  ) {
    super(dimension);
  }

  update(dt: number) {
    if (this.isComplete) {
      return;
    }

    const step = 1 / this.speed;
    const nextFrameIndex = (this.#currentFrameIndex + 1) % this.frames.length;
    const elapsedForNextFrame = nextFrameIndex * step;

    if (nextFrameIndex === 0) {
      const maxElapsed = step * this.frames.length;

      if (this.#elapsed >= maxElapsed) {
        this.#isFirstRunPassed = true;

        this.#elapsed = 0;
        this.#currentFrameIndex = 0;
      }
    } else if (this.#elapsed >= elapsedForNextFrame) {
      this.#currentFrameIndex = nextFrameIndex;
    }

    this.#elapsed += dt;
  }
}
